﻿/* Arquivo trab2_memoria.c
   Autor: Paulo Sergio Lopes de Souza

Observacoes:
(1)  Trabalho 2 - SSC0112 - Organizacao de Computadores Digitais I
(2)  Disponibilizado em 21/05/2012 - Data da entrega: Ver Moodle
(3)  Este arquivo trab2_memoria.c deve ser utilizado por todos os grupos.  
     Nao altere este arquivo. Parte da correcao sera automatizada 
     e este arquivo nao pode estar diferente.
(4)  Para realizar o seu trabalho, edite um arquivo chamado 
     memory_code.c Insira nele todas as funcionalidades necessarias
     ao seu trabalho.
(7)  A entrega do trabalho devera ser feita via Moodle.
     Forneca um único arquivo contendo o código desenvolvido e, 
     no começo do mesmo, informe os nomes dos integrantes que 
     participaram do desenvolvimento do trabalho. Por favor, identifique 
     a turma (T1 ou T2) e o nr do grupo no nome deste arquivo. 
(8)  Use o Linux para desenvolver o seu trabalho. Para compilar 
     use:  gcc trab2_memoria.c -o trab2_memory.
(9)  Use o Linux para executar e testar o seu trabalho. Para executar
     use: trab2_memory.
*/

#include <stdio.h>
#include <stdlib.h>

#define RAM_SIZE  256
#define CACHE_SIZE 8

/****************************
definicao de variaveis globais
****************************/
int memory[RAM_SIZE];  
/* Memoria RAM. Um vetor de palavras com 4 bytes cada uma. */

struct set {
        char  b0_ctl;       /* bits de controle do bloco 0 */
        int   b0_tag;		/* rotulo do bloco 0 */
        int   b0_w0, b0_w1; /* palavras do bloco 0 */

        char  b1_ctl;       /* bits de controle do bloco 1 */
        int   b1_tag;		/* rotulo do bloco 1 */
        int   b1_w0, b1_w1; /* palavras do bloco 1 */
/* *******************************************
os bits de controle (b0_ctl e b1_ctl) sao usados da seguinte maneira:
o bit -sig indica Validade do Bloco (1 para bloco valido e 0 para bloco nao valido)
2.o bit -sig e usado para LRU (1 e o LRU)
3o. bit -sig usado para Write Back (1 indica bloco modificado e 0 indica bloco nao modificado).
************************************************/
};
struct set cache[CACHE_SIZE];


/***********************
  prototipacao inicial
 ***********************/
int main (void);
int memory_access( int addr,  int *data,  int type );

/* o memory_code.c abaixo tem as funcoes desenvolvidas por voce neste Trab2*/
#include "memory_code.c"

int main (void)
{
	int i;
    int type, addr, data, success;
	
	// limpando memoria e cache
	for (i = 0; i < RAM_SIZE; i++) {
		memory[i] = 0;
	}
    for (i = 0; i < CACHE_SIZE; i++) {
	   cache[i].b0_ctl = 0;
	   cache[i].b0_tag = 0;
	   cache[i].b0_w0 = 0;
	   cache[i].b0_w1 = 0;
	   cache[i].b1_ctl = 0;
	   cache[i].b1_tag = 0;
	   cache[i].b1_w0 = 0;
	   cache[i].b1_w1 = 0;
	}

	// loop principal para solicitar os acessos
	while(1)  
	{ 
		printf("Entre com o tipo de acesso (0-Leitura, 1-Escrita ou -1 Encerra o Programa): ");
		scanf("%d", &type);
		printf("\n");
		if (type != 0 && type != 1 && type != -1) {
			printf("Tipo de acesso errado. Digite um correto! \n");
			continue;
		}
		if(type == -1) {
			printf("Encerrando o trab2! \n");
			break;
		}
		
	      printf("Digite o endereco *a Byte*: ");
		scanf("%d", &addr);
		printf("\n");
		// RAM_SIZE*4 - 4 indica o ultimo endereco *a Byte* valido para RAM_SIZE palavras
		if (addr < 0 || addr > ((RAM_SIZE*4)-4) || addr % 4 != 0)  {
			printf("Endereco invalido. Retornando ao comeco! \n");
			continue;
		}

	    // se for escrita, pede o dado para escrever na memoria
	    if (type == 1 ) { 
			  printf("Digite o dado para a escrita: ");
			  scanf("%d", &data);
			  printf("\n");
		}
		
		// faz o acesso a memoria
		success =  memory_access(addr, &data, type);
		if (success)
			printf("Sucesso!\n");
		else
			printf("Falha!\n");
	
	} // fim do loop para solicitar os acessos

	// imprime posicoes da memoria que estao ocupadas
	printf("\n");
	for (i = 0; i < RAM_SIZE; i++) {
		if(memory[i] != 0)
			  printf("Memory[%d]=%d\n", i, memory[i]);
	}

      // imprime conteudo da cache
      printf("\n");
      for (i = 0; i < CACHE_SIZE; i++) {
	    printf("Set[%d]-B0[ctl=%d, tag=%d, w0=%d, w1=%d] e B1[ctl=%d, tag=%d, w0=%d, w1=%d] \n", i, cache[i].b0_ctl, cache[i].b0_tag, cache[i].b0_w0, cache[i].b0_w1, cache[i].b1_ctl, cache[i].b1_tag, cache[i].b1_w0, cache[i].b1_w1);
	}
	
// 	printf("\n");
// 	printf("\n");
// 	printf("\nMEMORIA RAM: ");
// 	
	exit(0);
} // fim da main

